package com.wwu.system.controller;

import cn.hutool.captcha.LineCaptcha;
import cn.hutool.captcha.generator.MathGenerator;
import cn.hutool.captcha.generator.RandomGenerator;
import cn.hutool.core.util.RandomUtil;
import com.wwu.common.constant.CommConst;
import com.wwu.common.constant.SecurityConst;
import com.wwu.common.enums.MenuBtnEnum;
import com.wwu.common.utils.AssertUtil;
import com.wwu.common.web.CaptchaObj;
import com.wwu.common.web.ResultObj;
import com.wwu.system.common.aspect.Log;
import com.wwu.system.common.security.SecurityUtil;
import com.wwu.system.entity.SysParam;
import com.wwu.system.entity.SysUser;
import com.wwu.system.service.ISysConfigService;
import com.wwu.system.service.ISysMenuService;
import com.wwu.system.service.ISysParamService;
import io.swagger.annotations.*;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 *  用户登陆前端控制器
 * @author 一蓑烟雨
 * @date 2021-10-26 19:37
 * @version 1.0.0
 **/
@Api(tags = "用户登陆控制器(UserLoginController)")
@ApiSort(2)
@Controller
public class UserLoginController {
    /** 注入系统配置服务类 */
    @Resource
    private ISysConfigService sysConfigService;
    /** 注入系统参数服务类 */
    @Resource
    private ISysParamService sysParamService;
    /** 注入系统菜单服务类 */
    @Resource
    private ISysMenuService sysMenuService;

    /**
     * 登陆页，传递系统配置信息给登陆页
     * 跳转到templates的login.html
     * @param model
     * @return java.lang.String
     * @author 一蓑烟雨
     * @date 2023/5/30 15:34
     */
    @GetMapping("/")
    public String init(Model model) {
        model.addAttribute(CommConst.SYS_CONFIG, sysConfigService.getSysConfig());
        return "login";
    }

    /**
     * 登陆成功跳转首页，传递系统配置信息、用户信息给首页
     * @param model
     * @return java.lang.String
     * @author 一蓑烟雨
     * @date 2023/5/31 8:58
     */
    @GetMapping("/index")
    public String indexHtml(Model model) {
        //传递当前用户信息属性
        model.addAttribute(CommConst.SYS_USER, SecurityUtil.getCurrUser());
        //传递系统配置信息属性
        model.addAttribute(CommConst.SYS_CONFIG, sysConfigService.getSysConfig());

        //传递判断系统是否是默认密码的属性
        model.addAttribute("defaultPassword",false);
        //获取配置中的初始密码
        SysParam sysParam = sysParamService.getParamByKey("system|user|password");
        if(null != sysParam && StringUtils.hasText(sysParam.getParamValue())){
            SysUser sysUser = SecurityUtil.getCurrUser();
            //默认密码加密后与当前用户密码进行比对
            if(SecurityUtil.validatePassword(sysParam.getParamValue(),sysUser.getPassword())){
                model.addAttribute("defaultPassword",true);
            }
        }
        return "index";
    }

    /**
     * 默认显示工作台欢迎页，传递系统配置信息给工作台
     * @param model
     * @return java.lang.String
     * @author 一蓑烟雨
     * @date 2023/5/31 8:58
     */
    @GetMapping("/welcome")
    public String welcomeHtml(Model model) {
        model.addAttribute(CommConst.SYS_CONFIG, sysConfigService.getSysConfig());
        return "welcome";
    }

    @ApiOperation(value = "获取验证码")
    @ApiOperationSupport(order = 1)
    @GetMapping(value = "/captcha",produces = "image/jpeg")
    public void getCaptcha(HttpSession session, HttpServletResponse response) throws IOException {
        //设置过期的时间期限
        response.setDateHeader("Expires",0);
        //响应缓存设置
        response.setHeader("Cache-Control","no-store,no-cache,must-revalidate");
        response.setHeader("Cache-Control","post-check=0,pre-check=0");
        response.setHeader("Pragma","no-cache");
        response.setContentType("image/jpeg");

        //生成验证码：设置图形验证码的长、宽、验证码字符数、干扰线数量
        LineCaptcha captcha = new LineCaptcha(80, 30, 4, 20);
        //验证码类型默认为四则运算方式
        captcha.setGenerator(new MathGenerator(1));
        SysParam sysParam = sysParamService.getParamByKey("system|user|captcha|type");
        if(null != sysParam && StringUtils.hasText(sysParam.getParamValue())){
            if("0".equals(sysParam.getParamValue())){
                //0 纯数字
                captcha.setGenerator(new RandomGenerator("0123456789",4));
            }else if("1".equals(sysParam.getParamValue())){
                //1 英文字母
                captcha.setGenerator(new RandomGenerator("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",4));
            }else if("2".equals(sysParam.getParamValue())){
                //2 英文字母和数字
                captcha.setGenerator(new RandomGenerator("abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ",4));
            }
        }

        // 重新生成code
        captcha.createCode();

        //将验证码及过期时间存储到session中
        session.setAttribute(SecurityConst.CAPTCHA, new CaptchaObj(captcha,2*60));
        ServletOutputStream outputStream = response.getOutputStream();
        captcha.write(outputStream);
        outputStream.flush();
        outputStream.close();
    }

    /**
     * SpringSecurity框架内部提供了的登陆表单的实现，本方法不会被调用。该方法主要是给Swagger2调用使用
     * @param username  用户名
     * @param password  密码
     * @param captcha  验证码
     * @param request  前端请求
     * @return com.wwu.common.web.ResultObj
     * @author 一蓑烟雨
     * @date 2023/6/16 11:06
     */
    @ApiOperation(value = "用户登陆")
    @ApiOperationSupport(order = 2)
    @PostMapping("/login")
    public ResultObj login(String username, String password, String captcha, HttpServletRequest request){
        return  ResultObj.success(SecurityConst.LOGIN_SUCCESS);
    }

    @Log(menuName = "用户登陆",menuBtnEnum = MenuBtnEnum.LOCK)
    @ApiOperation(value = "页面解锁，验证密码")
    @ApiOperationSupport(order = 3)
    @ApiImplicitParam(name = "password", value = "输入密码",paramType = "query", required = true)
    @PostMapping("/unlock")
    @ResponseBody
    public ResultObj unlock(String password){
        AssertUtil.isTrue(!StringUtils.hasText(password),"请输入登陆密码");
        SysUser sysUser = SecurityUtil.getCurrUser();
        AssertUtil.isTrue(ObjectUtils.isEmpty(sysUser),"用户信息异常");
        //默认密码加密后与当前用户密码进行比对
        if(!SecurityUtil.validatePassword(password,sysUser.getPassword())){
            return ResultObj.error("密码错误");
        }
        return ResultObj.success();
    }

    @ApiOperation(value = "动态获取导航菜单")
    @ApiOperationSupport(order = 4)
    @GetMapping("/initMenu")
    @ResponseBody
    public String initMenu(){
        return  sysMenuService.initMenu();
    }
}